package com.lenovo.lcdm.access.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lenovo.lcdm.access.dto.MenuDto;
import com.lenovo.lcdm.access.dto.MenuTreeDto;
import com.lenovo.lcdm.access.entity.AccessMenu;
import com.lenovo.lcdm.access.mapper.AccessMenuMapper;
import com.lenovo.lcdm.access.service.AccessMenuService;
import com.lenovo.lcdm.access.service.AccessPolicyService;
import com.lenovo.lcdm.common.enums.CommonMsgEnum;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.team.common.util.ContextUtil;
import com.lenovo.lcdm.access.util.ObjectUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author xujing30
* @description 针对表【access_menu】的数据库操作Service实现
* @createDate 2024-02-01 17:23:24
*/
@Service
public class AccessMenuServiceImpl extends ServiceImpl<AccessMenuMapper, AccessMenu>
    implements AccessMenuService{

    @Autowired
    private AccessPolicyService accessPolicyService;

    private static final Long rootId = 0L;

    @Override
    public boolean saveMenu(MenuDto menuDto) {
        checkMenu(menuDto, true);
        AccessMenu menu = new AccessMenu();
        BeanUtils.copyProperties(menuDto, menu);
        menu.setCreateTime(LocalDateTime.now());
        menu.setModifyTime(LocalDateTime.now());
        menu.setCreator(ContextUtil.getCurrentUser());
        menu.setModifier(ContextUtil.getCurrentUser());
        return save(menu);
    }

    private void checkMenu(MenuDto menuDto, boolean isCreate){
        if(ObjectUtil.isAnyEmpty(menuDto.getParentId(), menuDto.getName())){
            throw new BusinessException("Parameters cannot be empty.", CommonMsgEnum.FAIL.getCode());
        }
        if(!isCreate && menuDto.getId() == null){
            throw new BusinessException("Parameters id cannot be empty.", CommonMsgEnum.FAIL.getCode());
        }
    }

    @Override
    public boolean updateMenu(MenuDto menuDto) {
        checkMenu(menuDto, false);
        AccessMenu menu = getById(menuDto.getId());
        if(menu == null){
            throw new BusinessException("Menu does not exist.", CommonMsgEnum.FAIL.getCode());
        }
        BeanUtils.copyProperties(menuDto, menu);
        menu.setModifyTime(LocalDateTime.now());
        menu.setModifier(ContextUtil.getCurrentUser());
        return saveOrUpdate(menu);
    }

    @Override
    public boolean deleteMenu(Long id) {
        AccessMenu menu = getById(id);
        if(menu == null){
            throw new BusinessException("Cannot find the menu.", CommonMsgEnum.FAIL.getCode());
        }
        accessPolicyService.removeByMenuId(id);
        return this.removeById(id);
    }

    @Override
    public MenuDto getMenuById(Long id) {
        MenuDto menuDto = new MenuDto();
        AccessMenu menu = getById(id);
        BeanUtils.copyProperties(menu, menuDto);
        AccessMenu parentMenu = getById(menu.getParentId());
        menuDto.setParentName(parentMenu.getName());
        return menuDto;
    }

    @Override
    public MenuTreeDto getMenuTree() {
        MenuTreeDto menuTreeDto = new MenuTreeDto();
        AccessMenu root = getById(rootId);
        BeanUtils.copyProperties(root, menuTreeDto);
        findChildren(menuTreeDto, rootId);
        return menuTreeDto;
    }

    /**
     * 查找子树
     * @param menuTreeDto
     * @param parentId
     */
    private void findChildren(MenuTreeDto menuTreeDto, Long parentId) {
        LambdaQueryWrapper<AccessMenu> qw = new LambdaQueryWrapper();
        qw.eq(AccessMenu::getParentId, parentId);
        List<AccessMenu> children = list(qw);
        menuTreeDto.setChildren(children.stream().map(item -> {
            MenuTreeDto treeDto = new MenuTreeDto();
            BeanUtils.copyProperties(item, treeDto);
            findChildren(treeDto, item.getId());
            return treeDto;
        }).collect(Collectors.toList()));
    }

}




